/****************************************************************************
 *
 * Copyright 2016 Samsung Electronics All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 *
 ****************************************************************************/

/*****************************************************************************
* fsm.h - Network Control Protocol Finite State Machine header file.
*
* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc.
* Copyright (c) 1997 Global Election Systems Inc.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
* REVISION HISTORY
*
* 03-01-01 Marc Boucher <marc@mbsi.ca>
*   Ported to lwIP.
* 97-11-05 Guy Lancaster <glanca@gesn.com>, Global Election Systems Inc.
*   Original based on BSD code.
*****************************************************************************/
/*
 * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions.
 *
 * Copyright (c) 1989 Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Carnegie Mellon University.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * $Id: fsm.h,v 1.5 2009/12/31 17:08:08 goldsimon Exp $
 */

#ifndef FSM_H
#define FSM_H

/*
 * LCP Packet header = Code, id, length.
 */
#define HEADERLEN (sizeof(u_char) + sizeof(u_char) + sizeof(u_short))

/*
 *  CP (LCP, IPCP, etc.) codes.
 */
#define CONFREQ     1			/* Configuration Request */
#define CONFACK     2			/* Configuration Ack */
#define CONFNAK     3			/* Configuration Nak */
#define CONFREJ     4			/* Configuration Reject */
#define TERMREQ     5			/* Termination Request */
#define TERMACK     6			/* Termination Ack */
#define CODEREJ     7			/* Code Reject */

/*
 * Each FSM is described by an fsm structure and fsm callbacks.
 */
typedef struct fsm {
	int unit;					/* Interface unit number */
	u_short protocol;			/* Data Link Layer Protocol field value */
	int state;					/* State */
	int flags;					/* Contains option bits */
	u_char id;					/* Current id */
	u_char reqid;				/* Current request id */
	u_char seen_ack;			/* Have received valid Ack/Nak/Rej to Req */
	int timeouttime;			/* Timeout time in milliseconds */
	int maxconfreqtransmits;	/* Maximum Configure-Request transmissions */
	int retransmits;			/* Number of retransmissions left */
	int maxtermtransmits;		/* Maximum Terminate-Request transmissions */
	int nakloops;				/* Number of nak loops since last ack */
	int maxnakloops;			/* Maximum number of nak loops tolerated */
	struct fsm_callbacks *callbacks;	/* Callback routines */
	char *term_reason;			/* Reason for closing protocol */
	int term_reason_len;		/* Length of term_reason */
} fsm;

typedef struct fsm_callbacks {
	void (*resetci)(fsm *);	/* Reset our Configuration Information */
	int (*cilen)(fsm *);		/* Length of our Configuration Information */
	void (*addci)(fsm *, u_char *, int *);	/* Add our Configuration Information */
	int (*ackci)(fsm *, u_char *, int);	/* ACK our Configuration Information */
	int (*nakci)(fsm *, u_char *, int);	/* NAK our Configuration Information */
	int (*rejci)(fsm *, u_char *, int);	/* Reject our Configuration Information */
	int (*reqci)(fsm *, u_char *, int *, int);	/* Request peer's Configuration Information */
	void (*up)(fsm *);			/* Called when fsm reaches LS_OPENED state */
	void (*down)(fsm *);		/* Called when fsm leaves LS_OPENED state */
	void (*starting)(fsm *);	/* Called when we want the lower layer */
	void (*finished)(fsm *);	/* Called when we don't want the lower layer */
	void (*protreject)(int);	/* Called when Protocol-Reject received */
	void (*retransmit)(fsm *);	/* Retransmission is necessary */
	int (*extcode)(fsm *, int, u_char, u_char *, int);	/* Called when unknown code received */
	char *proto_name;			/* String name for protocol (for messages) */
} fsm_callbacks;

/*
 * Link states.
 */
#define LS_INITIAL  0			/* Down, hasn't been opened */
#define LS_STARTING 1			/* Down, been opened */
#define LS_CLOSED   2			/* Up, hasn't been opened */
#define LS_STOPPED  3			/* Open, waiting for down event */
#define LS_CLOSING  4			/* Terminating the connection, not open */
#define LS_STOPPING 5			/* Terminating, but open */
#define LS_REQSENT  6			/* We've sent a Config Request */
#define LS_ACKRCVD  7			/* We've received a Config Ack */
#define LS_ACKSENT  8			/* We've sent a Config Ack */
#define LS_OPENED   9			/* Connection available */

/*
 * Flags - indicate options controlling FSM operation
 */
#define OPT_PASSIVE 1			/* Don't die if we don't get a response */
#define OPT_RESTART 2			/* Treat 2nd OPEN as DOWN, UP */
#define OPT_SILENT  4			/* Wait for peer to speak first */

/*
 * Prototypes
 */
void fsm_init(fsm *);
void fsm_lowerup(fsm *);
void fsm_lowerdown(fsm *);
void fsm_open(fsm *);
void fsm_close(fsm *, char *);
void fsm_input(fsm *, u_char *, int);
void fsm_protreject(fsm *);
void fsm_sdata(fsm *, u_char, u_char, u_char *, int);

/*
 * Variables
 */
extern int peer_mru[];			/* currently negotiated peer MRU (per unit) */

#endif							/* FSM_H */
